class DivContainer{
    cellSize = 100
    container ={} //DivContainer对应的DOM文档
    rowNum = 0
    columnNum = 0
    divArray=[[]]    //DivContainer中存放的DivMover

    constructor(container =null,cellSize = 100){
        this.container = container
        this.cellSize = cellSize
        this.columnNum = Math.floor(container.scrollWidth / cellSize)
        this.rowNum = Math.round(container.scrollHeight / cellSize)
        this.initArea()

        Object.defineProperty(this,"height",{//数据代理，界面高度
            get(){
                console.log('containerHeight geted',container.scrollHeight)
                return container.scrollHeight
            },
            set(newHeight){
                // this.container.style.height = `${newHeight}px` //不赋值container的height，反而能使得减少时窗口自动回缩到初始值
                this.rowNum = Math.round(newHeight/this.cellSize)
                this.updateDivArray()
                console.log('containerHeight changed,new Height',container.scrollHeight)
            }
        })
        Object.defineProperty(this,"width",{//数据代理，界面宽度
            get(){
                console.log('containerHeight geted',container.scrollWidth)
                return container.scrollWidth
            }
        })

        this.container.addEventListener('contextmenu',(e)=>{
            e.preventDefault(); // 阻止默认的上下文菜单
            document.querySelectorAll(".moverMenu").forEach((element)=>{
                element.remove()
            })
        })

    }

    initArea(){
        // this.areaArray = Array.from({ length: height }, () => Array(width).fill(0));
        this.divArray = Array.from({ length: this.rowNum }, () => 
            Array.from({ length: this.columnNum }, () => ({ occupy: 0, divMoverObj: null }))
        );
    }

    updateDivArray(){
        let newAreaArray = Array.from({ length: this.rowNum }, () => 
            Array.from({ length: this.columnNum }, () => ({ occupy: 0, divMoverObj: null }))
        );
        
        for(let i = 0;i < this.divArray.length;i++){
            for(let j = 0;j < this.divArray[0].length;j++){
                newAreaArray[i][j] = this.divArray[i][j]
                console.log(i,",",j)
            }
        }
        this.divArray = newAreaArray
        console.log('updateDivArray funciton execute,this.rowNum new value:',this.rowNum)
    }

    extendArea(extendHeight){
        this.height = this.height + extendHeight
    }

    checkOccupy(elementOffsetX,elementOffsetY,elementWidth,elementHeight){
        let X = Math.round(parseInt(elementOffsetX) / this.cellSize)
        let Y = Math.round(parseInt(elementOffsetY) / this.cellSize)
        let Width = Math.round(parseInt(elementWidth) / this.cellSize)
        let Height = Math.round(parseInt(elementHeight) / this.cellSize)
        
        if(X < 0 || Y < 0 || X+Width > this.columnNum ){//越界检测
            // console.log('元素越界');
            return "crossBorder"
        }
        if(Y+Height > this.rowNum){//下移元素自动扩宽container
            this.extendArea(this.cellSize)
        }
        for(let i = Y;i < Y+Height ;i++){
            for(let j =X;j < X+Width;j++){
                if (this.divArray[i] && this.divArray[i][j].occupy === 1) {
                    // console.log('区域已被占用');
                    return this.divArray[i][j].divMoverObj; // 区域已被占用，返回占用位置的对象
                }
            }
        }
        return "free"
    }

    occupyAreaContainDivMover(elementOffsetX,elementOffsetY,elementWidth,elementHeight,Obj){//占用区域
        //除以单元格宽度，转换为数组长宽
        let X = Math.round(parseInt(elementOffsetX) / this.cellSize)
        let Y = Math.round(parseInt(elementOffsetY) / this.cellSize)
        let Width = Math.round(parseInt(elementWidth) / this.cellSize)
        let Height = Math.round(parseInt(elementHeight) / this.cellSize)

        try{
            const flag = X instanceof Number && Y instanceof Number && Width instanceof Number && Height instanceof Number
            if(flag){
                throw new Error("DivContainer.occupyAreaContainDivMover占领位置参数错误")
            }
            if(X < 0 || Y < 0 || X+Width > this.columnNum || Y+Height > this.rowNum){//检测元素是否越界
                console.log('元素越界，无法标记');
                return false
            }
            // 检查区域是否被占用
            for(let i = Y;i < Y+Height ;i++){
                for(let j =X;j < X+Width;j++){
                    if (this.divArray[i] && this.divArray[i][j].occupy === 1) {
                        console.log('区域已被占用，无法标记:',X,Y,Width,Height);
                        return false; // 区域已被占用，返回 false
                    }
                }
            }
            // 标记新区域
            for(let i = Y;i < Y+Height ;i++){
                for(let j =X;j < X+Width;j++) {
                    if (this.divArray[i] && this.divArray[i][j] !== undefined) {
                        this.divArray[i][j].occupy = 1;  //标记置为1
                        this.divArray[i][j].divMoverObj = Obj //放入元素
                    }
                }
            }
            // console.log("occupyAreaContainDivMover",{
            //     "X":X,
            //     "Y":Y,
            //     "Width":Width,
            //     "Height":Height
            // })
            return true; // 标记成功，返回 true
        }catch(e){
            console.error(e)
        }
    }

    clearArea(elementOffsetX,elementOffsetY,elementWidth,elementHeight){
        let X = Math.round(parseInt(elementOffsetX) / this.cellSize)
        let Y = Math.round(parseInt(elementOffsetY) / this.cellSize)
        let Width = Math.round(parseInt(elementWidth) / this.cellSize)
        let Height = Math.round(parseInt(elementHeight) / this.cellSize)

        console.log("clearArea",{
            "X":X,
            "Y":Y,
            "Width":Width,
            "Height":Height
        })
        
        if(X < 0 || Y < 0 || X+Width > this.columnNum || Y+Height > this.rowNum){
            console.log('清除越界，无法清除');
            return false
        }

        // 清除区域
        for(let i = Y;i < Y+Height ;i++){
            for(let j =X;j < X+Width;j++) {
                if (this.divArray[i] && this.divArray[i][j] !== undefined) {
                    this.divArray[i][j].occupy = 0
                    this.divArray[i][j].divMoverObj = null
                }
            }
        }
    }

    clearAllAreaAndElement(){
        // 清空区域数组
        for(let i = 0;i < this.columnNum ;i++){
            for(let j =0;j < this.rowNum;j++) {
                if (this.divArray[i] && this.divArray[i][j] !== undefined) {
                    this.divArray[i][j].occupy = 0
                    this.divArray[i][j].divMoverObj = null
                }
            }
        }

        //清空容器内的所有元素
        this.container.replaceChildren()
    }

    async setDivByJson(jsonUrl="./bookmarksContainUrlDataNoLevel.json"){
        try{
            //获取路径下的用于测试的json文件
            const response = await fetch(jsonUrl)
            if(!response.ok){
                throw new Error("fetch url error:",jsonUrl)
            }
            let jsonObj = await response.json() //将JSON变为数组对象
            //遍历该数组，将数组中的对象装入DivMover
            let i = 0,j = 0,joinDiv
            jsonObj.forEach(element => {
                if(i >= this.columnNum){
                    i = 0
                    j++
                }
                if(j >= this.rowNum){
                    this.height = this.height + this.cellSize
                }
                joinDiv = this.appendDiv(undefined,i,j,element.iconURL,element.title,element.url)//插入文档树
                i++
            })
            return jsonObj
        }catch(error){
            console.log("catch error:",error)
        }
    }

    appendDiv(divClassName = "myDiv",
                X,
                Y,
                icon = "https://www.baidu.com/favicon.ico",
                iconName ="baidu.com",url="www.baidu.com"){
        if(X > this.columnNum || Y > this.rowNum || this.columnNum < 0 || this.rowNum < 0){
            throw new Error(`append div error,X or Y exceed maxmium limit`)
        }
        iconName = iconName.split(/[-，,_ .]/)[0].trim().slice(0,6)
        let myDivObj = new DivMover(
            divClassName,
            X * this.cellSize,
            Y * this.cellSize,
            this.cellSize,
            this.cellSize,
            this,//divContainer
            icon,
            iconName,
            "divIcon",
            "divIconName",
            url
        )
        return myDivObj
    }

    appendFolderDiv({iconName,childrenDivMoverList,X,Y,width = 1,height = 1,divClassName = "myDiv",parentFolderMover = null},folderContainerObj){
        let divMoverObj = new DivMover(
            divClassName,
            X * this.cellSize,
            Y * this.cellSize,
            width*this.cellSize,
            height*this.cellSize,
            this,
            "./icon/folderblue.png",
            iconName,
            "divIcon",
            "divIconName",
            "这是一个文件夹"
        )
        new FolderMover(divMoverObj,childrenDivMoverList,parentFolderMover,folderContainerObj)
    }

    printLayoutByJSON(){
        let arr = new Array
        let processedElements = new Set(); // 用于记录已经处理过的元素
        this.divArray.flat().forEach(element=>{
            if(element.occupy === 0) return
            const elementKey = element.divMoverObj; // 获取元素的唯一标识符
            if (processedElements.has(elementKey)) {//跳过已经处理过的元素
                return;
            }
            let obj = {
                name:element.divMoverObj.iconName,
                icon:element.divMoverObj.icon,
                url:element.divMoverObj.url,
                x:Math.floor(element.divMoverObj.offsetLeft/this.cellSize),
                y:Math.floor(element.divMoverObj.offsetTop/this.cellSize),
                width:Math.floor(element.divMoverObj.moveDistanceX/this.cellSize),
                Height:Math.floor(element.divMoverObj.moveDistanceY/this.cellSize)
            }
            arr.push(obj)
            processedElements.add(elementKey);// 标记该元素已处理
        })
        console.log(JSON.stringify(arr))
    }

    cleanDivContainer(){
        for(let child of this.container.children){
            child.remove()
        }
    }

    divMoverCombine(mergeObjOne,mergeObjTwo){
        console.log('合并文件夹成功')
        if(mergeObjOne instanceof FolderMover){
            if(mergeObjTwo instanceof FolderMover){ //设置mergeObjTwo的文件夹parent为mergeObjOne
                mergeObjTwo.parentFolderMover = mergeObjOne
            }
            mergeObjOne.appendChild(mergeObjTwo)

        }else{
            let folderMover = new FolderMover(mergeObjOne,[mergeObjOne,mergeObjTwo])      
        }
        mergeObjTwo.destroyDivMover()  //摧毁元素                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   
    }
}